Skip to content

perf(utils): optimize hot-path utilities and fix isObject null bug#12

Merged
chiefcll merged 2 commits into
mainfrom
perf/utils-optimizations
May 16, 2026
Merged

perf(utils): optimize hot-path utilities and fix isObject null bug#12
chiefcll merged 2 commits into
mainfrom
perf/utils-optimizations

Conversation

@chiefcll
Copy link
Copy Markdown
Contributor

Summary

A bundle of small, contained optimizations across the utils modules, plus one correctness fix.

  • hexColor() (src/utils.ts) — swap String.replace + Number() for charCodeAt checks + parseInt(hex, 16). Called for every color prop.
  • isObject() (src/core/utils.ts) — bug fix: typeof null === 'object', so isObject(null) returned true, which made hasDebug(null) access .debug on null. Now guards against null.
  • flattenStyles() — replace forEach (per-array closure alloc) with indexed for loop.
  • Gaussian blur (createBlurredImage.ts) —
    • Kernel is normalized (sum = 1), so weightSum only deviates near edges. Precompute per-row/per-column inverse weight sums and use 1 for interior pixels — removes a divide and several adds per pixel.
    • Drop the redundant new Uint8ClampedArray(output) copy by writing horizontal pass straight into a dedicated temp buffer.
    • Hoist y * width out of inner loop.
  • Spatial navigation (handleNavigation.ts) —
    • distanceBetweenRectCenterssquaredDistanceBetweenRectCenters: drop Math.sqrt (only used for comparison) and the pointless /2 on dx/dy.
    • Replace children.entries() iterator with an indexed for loop in findClosestFocusableChildIdx.

Test plan

  • npm run tsc clean
  • npm run lint clean
  • npm test — 230/230 passing
  • Manual smoke test in a downstream app to confirm blurred images render identically and focus traversal feels unchanged

🤖 Generated with Claude Code

chiefcll and others added 2 commits May 16, 2026 11:11
- hexColor: replace regex/Number() with charCode + parseInt(hex, 16)
- isObject: guard against null (typeof null === 'object' bug)
- flattenStyles: indexed loop, no per-array closure allocation
- gaussian blur: precompute per-row/col edge weight sums (kernel sums
  to 1 in the interior), drop redundant Uint8ClampedArray copy
- spatial nav: compare squared distances (skip Math.sqrt) and replace
  children.entries() iterator with indexed loop in
  findClosestFocusableChildIdx

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Skip the intermediate `fns.filter(...)` array; the first two valid
  functions are tracked in locals, only allocating an array on the 3+
  case.
- Add a 2-function fast path that unrolls the loop entirely — this is
  the dominant call shape (props.onX + local handler, props.ref + local
  ref).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@chiefcll chiefcll merged commit 2afa9c8 into main May 16, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant